package com.apikey.auth.service.impl;

import com.apikey.auth.entity.Application;
import com.apikey.auth.entity.ApiKey;
import com.apikey.auth.repository.ApplicationRepository;
import com.apikey.auth.repository.ApiKeyRepository;
import com.apikey.auth.service.ReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 申请审核服务实现类
 * 提供申请审核相关的业务逻辑实现
 *
 * @author API Key Framework
 * @version 1.0
 */
@Service
@Transactional
public class ReviewServiceImpl implements ReviewService {

    @Autowired
    private ApplicationRepository applicationRepository;
    
    @Autowired
    private ApiKeyRepository apiKeyRepository;

    /**
     * 审核申请 - 通过
     *
     * @param applicationId 申请ID
     * @param reviewer      审核人
     * @param remark        审核备注
     * @return 审核后的申请记录
     */
    @Override
    public Application approveApplication(Long applicationId, String reviewer, String remark) {
        validateReviewParams(applicationId, reviewer, remark);
        validateApplicationForReview(applicationId);
        
        Application application = applicationRepository.findById(applicationId)
                .orElseThrow(() -> new IllegalArgumentException("申请记录不存在"));
        
        // 审核通过
        application.review(Application.Status.APPROVED.getCode(), reviewer, remark);
        Application savedApplication = applicationRepository.save(application);
        
        // 生成API Key
        generateApiKeyForApplication(savedApplication);
        
        return savedApplication;
    }

    /**
     * 审核申请 - 拒绝
     *
     * @param applicationId 申请ID
     * @param reviewer      审核人
     * @param remark        拒绝原因
     * @return 审核后的申请记录
     */
    @Override
    public Application rejectApplication(Long applicationId, String reviewer, String remark) {
        validateReviewParams(applicationId, reviewer, remark);
        validateApplicationForReview(applicationId);
        
        Application application = applicationRepository.findById(applicationId)
                .orElseThrow(() -> new IllegalArgumentException("申请记录不存在"));
        
        // 审核拒绝
        application.review(Application.Status.REJECTED.getCode(), reviewer, remark);
        return applicationRepository.save(application);
    }

    /**
     * 为通过的申请生成API Key
     *
     * @param application 申请记录
     * @return 生成的API Key
     */
    @Override
    public ApiKey generateApiKeyForApplication(Application application) {
        if (application == null) {
            throw new IllegalArgumentException("申请记录不能为空");
        }
        
        if (!application.isApproved()) {
            throw new IllegalStateException("只有审核通过的申请才能生成API Key");
        }
        
        // 检查是否已经生成过API Key
        if (apiKeyRepository.existsByApplicationIdAndIsDeletedFalse(application.getId())) {
            throw new IllegalStateException("该申请已经生成过API Key");
        }
        
        // 生成API Key
        ApiKey apiKey = new ApiKey();
        apiKey.setName("API Key for " + application.getPhoneNumber());
        apiKey.setKeyValue(generateApiKeyValue());
        apiKey.setApplicationId(application.getId());
        apiKey.setUserId(application.getPhoneNumber()); // 使用手机号作为用户ID
        apiKey.setStatus("ACTIVE");
        apiKey.setPermissions("read,write"); // 默认权限
        apiKey.setDailyLimit(1000); // 默认每日限制
        apiKey.setMonthlyLimit(30000); // 默认每月限制
        apiKey.setExpiresAt(LocalDateTime.now().plusYears(1)); // 默认1年有效期
        apiKey.setDescription("通过申请系统生成的API Key");
        
        return apiKeyRepository.save(apiKey);
    }

    /**
     * 验证申请是否可以审核
     *
     * @param applicationId 申请ID
     * @throws IllegalStateException 申请状态不允许审核时抛出
     */
    @Override
    public void validateApplicationForReview(Long applicationId) {
        if (applicationId == null) {
            throw new IllegalArgumentException("申请ID不能为空");
        }
        
        Application application = applicationRepository.findById(applicationId)
                .orElseThrow(() -> new IllegalArgumentException("申请记录不存在"));
        
        if (application.isReviewed()) {
            throw new IllegalStateException("该申请已经审核过，不能重复审核");
        }
        
        if (!Application.Status.PENDING.getCode().equals(application.getStatus())) {
            throw new IllegalStateException("只有待审核状态的申请才能进行审核");
        }
    }

    /**
     * 验证审核参数
     *
     * @param applicationId 申请ID
     * @param reviewer      审核人
     * @param remark        审核备注
     * @throws IllegalArgumentException 参数验证失败时抛出
     */
    @Override
    public void validateReviewParams(Long applicationId, String reviewer, String remark) {
        if (applicationId == null) {
            throw new IllegalArgumentException("申请ID不能为空");
        }
        
        if (!StringUtils.hasText(reviewer)) {
            throw new IllegalArgumentException("审核人不能为空");
        }
        
        if (reviewer.length() > 50) {
            throw new IllegalArgumentException("审核人名称长度不能超过50个字符");
        }
        
        if (StringUtils.hasText(remark) && remark.length() > 500) {
            throw new IllegalArgumentException("审核备注长度不能超过500个字符");
        }
    }

    /**
     * 生成API Key值
     *
     * @return API Key值
     */
    private String generateApiKeyValue() {
        String prefix = "ak_";
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return prefix + uuid;
    }
}